package com.ghost.manager
{
	import com.adobe.cairngorm.control.CairngormEventDispatcher;
	import com.ghost.data.Base_send;
	import com.ghost.event.SocketEvent;
	import com.ghost.utils.BytesUtil;
	import com.ghost.utils.Debug;
	
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.Socket;
	import flash.utils.ByteArray;
	import flash.utils.Endian;

	/**
	 * @author ghost
	 * 数据通信管理
	 */	
	public class Socket_manager
	{
		private static var instance:Socket_manager;
		public static function getInstance():Socket_manager
		{
			if(instance == null)
			{
				instance = new Socket_manager();
			}
			return instance;
		}
		private var socket:Socket;
		public var consocket:Boolean = false;
		public var connSucFun:Function;
		public var fault:Function;
		private var readBuffer:ByteArray;
		private var msg_l:int;//数据长度
		private var head_l:int=2;//数据协议头的长度
		public function Socket_manager()
		{
			socket=new Socket();//创建Socket对象
			readBuffer = new ByteArray();
			//readBuffer.endian = Endian.LITTLE_ENDIAN;
			socket.endian = Endian.LITTLE_ENDIAN;//数据的字节顺序(little多字节数字的最低有效字节位于字节序列的最前面 big多字节数字的最高有效字节位于字节序列的最前面)
			socket.addEventListener(Event.CLOSE,onClose);//连接关闭时触发
			socket.addEventListener(Event.CONNECT,onComplete);//连接成功时触发
			socket.addEventListener(ProgressEvent.SOCKET_DATA,getData);//服务器端有数据过来的时候触发
			socket.addEventListener(IOErrorEvent.IO_ERROR,onIOError);//网络出错的时候触发
			socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,onSecurity);//出现安全沙箱错误的时候触发
		}
		public function connSocket(url:String,pt:Number,sucFun:Function=null,faultFun:Function=null):void
		{
			connSucFun = sucFun ;
			fault = faultFun;
			socket.connect(url,pt);
		}
		private function onClose(e:Event):void
		{
			consocket = false;
			var event:SocketEvent = new SocketEvent(SocketEvent.CLOSE_EVENT);
			CairngormEventDispatcher.getInstance().dispatchEvent(event);
		}
		private function onComplete(e:Event):void
		{
			consocket = true;
			Debug.log('socket success');
			if(connSucFun!=null)connSucFun();
		}
		public function send(send_bt:Base_send):void
		{
			if(consocket == true)
			{
				var bytes:ByteArray = send_bt.DataToByteArray();
				socket.writeBytes(bytes);
				socket.flush();
			}
		}
		private function getData(e:ProgressEvent):void
		{
			parse_data();
		}
		//解析数据
		private function parse_data():void{
			//开始读取数据的标记
			var readFlag:Boolean = false;
			//每读取一条数据bytesAvailable值将随之减少
			while (socket.bytesAvailable) {
				if (!readFlag && socket.bytesAvailable >= head_l) {
					//读取数据长度
					msg_l = socket.readShort();
					readFlag = true;
				}
				//如果为0,表示收到异常消息，避免无限循环地等待
				if(msg_l==0){
					return;
				}
				//数据流里的数据满足条件，开始读数据
				if (readFlag && socket.bytesAvailable >= msg_l){
					//指针回归
					readBuffer.position = 0;
					//取出指定长度的字节
					socket.readBytes(readBuffer, 0, msg_l);
					//读取完一条消息后发送消息内容
					BytesUtil.read_bytes(readBuffer,Dispense_manager.getinstance().init);
					msg_l = 0;
					readFlag = false;
				}
			}
		}
		private function onIOError(e:IOErrorEvent):void 
		{
			consocket = false;
			Debug.log('socket fault');
			if(fault!=null)fault();
		}
		private function onSecurity(e:SecurityErrorEvent):void 
		{
			consocket = false;
			Debug.log('socket fault');
			if(fault!=null)fault();
		}
		/* 关闭与后台通信 */
		public function close_net():void
		{
			socket.close();
			Debug.log('socket is closed');
			consocket = false;
		}
	}
}